package com.zjun.chain;

import com.zjun.ApplicationContextHolder;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 责任抽象链上下文
 */
public final class AbstractHainContext<T> implements CommandLineRunner {
    private final Map<String, List<AbstractChainHandler>> abstractChainContainer = new HashMap<>();

    public void handler(String mark,T requestParam){
        List<AbstractChainHandler> abstractChainHandlers = abstractChainContainer.get(mark);
        if (CollectionUtils.isEmpty(abstractChainHandlers)){
            throw new RuntimeException("[AbstarctChainContext]"+String.format("[%s] Chain of Responsibility ID is undefined.", mark));
        }
        abstractChainHandlers.forEach(each -> each.handler(requestParam));
    }


    //继承CommandLineRunner:当应用程序启动时，`CommandLineRunner` 接口的实现类中的 `run` 方法会被调用
    @Override
    public void run(String... args) throws Exception {
        Map<String, AbstractChainHandler> chainFilterMap = ApplicationContextHolder.getBeansOfType(AbstractChainHandler.class);
        chainFilterMap.forEach((beanName,bean)->{
            List<AbstractChainHandler> abstractChainHandlers = abstractChainContainer.get(bean.mark());
            //如果abstarctChainer中没有这个处理,添加一个新的
            if (CollectionUtils.isEmpty(abstractChainHandlers)){
                abstractChainHandlers = new ArrayList<>();
            }
            abstractChainHandlers.add(bean);
            abstractChainHandlers.stream()
                    .sorted(Comparator.comparing(Ordered::getOrder))
                    .collect(Collectors.toList());
            abstractChainContainer.put(bean.mark(),abstractChainHandlers);
        });
    }
}
